IoT Coreで受け取ったデータをCloudWatchで状態監視してみた
はじめに
IoT Coreで受け取った測定データが特定のしきい値を超えた場合に通知を受け取りたいことってありますよね??
また、実際に機器を扱う現場ではアラートが出た後、しきい値を下回った場合にも通知を受け取りたいということも多いと思います。
今回は受け取ったデータを可視化サービスで通知設定したり、lambdaで加工したり、DBに保存してなんやかんやしなくても、IoT CoreとCloudWatchを使って上記の仕組みを簡単に作る方法をご紹介します。
やりたいことをイラストにするとこんな感じです。
しきい値を超えた場合に通知を受け、正常に戻った場合も通知を受けとります。
条件
今回は以下の条件で通知を行いたいと思います。
- 値が30.0を超えたらアラート通知
- ステータスがアラート状態から正常に回復した場合に回復通知
しきい値は整数しか設定できません。
そのため小数点以下の精度で判断が必要な場合は別のソリューションが必要です。
全体図
まずは全体のアーキテクチャです。
設定の流れをざっくりまとめるとこんな感じです。
- IoT Coreでデータ受け取る
- IoT CoreのルールでCloudWatchのカスタムメトリクスに転送する
- CloudWatchアラームでしきい値ベースのアラームを設定する(同時に解除通知も設定)
それでは実際に作っていきましょう。
今回は再現性を高くするためにAWS CLIで作成していきます。
IAM
まずはIoTルールに必要なロールとポリシーを作成します。
値は適宜読み替えてください。
aws iam create-role \
--role-name demo-role-iot-rule-alart \
--assume-role-policy-document \
'{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "iot.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}'
インラインポリシー
aws iam put-role-policy \
--role-name demo-role-iot-rule-alart \
--policy-name demo-inline-policy-iot-rule-alart \
--policy-document \
'{
"Version": "2012-10-17",
"Statement":
{
"Effect": "Allow",
"Action": "cloudwatch:PutMetricData",
"Resource": "*"
}
}'
ここで作成したロールは次のIoTルールで使用します。
内容は機器から受け取ったデータをCloudWatchにPutするための権限です。
IoT Core
IoT Coreで受け取ったデータをCloudWatchへ転送するルールを作成します。
こちらのルールでは osaka/factory_a/thermometer/demo-device
というトピックに入ったデータの temp
の値をCloudWatchに送信します。
ロールARNは先ほど作成したロールのARNです。
以下のパラメータで作成します。
項目 | 値 |
---|---|
ルール名 | demo_iot_rule_temp_monitor |
SQL | SELECT temp FROM 'osaka/factory_a/thermometer/demo-device' |
アクション | CloudWatchメトリクスへ送信 |
メトリクス名 | temp |
メトリクス名前空間 | IoT/Device |
メトリクス値 | ${temp} |
メトリクス単位 | None |
ロールARN | arn:aws:iam::<account-id>:role/demo-role-iot-rule-alart |
aws iot create-topic-rule \
--region ap-northeast-1 \
--rule-name "demo_iot_rule_temp_monitor" \
--topic-rule-payload '{
"awsIotSqlVersion": "2016-03-23",
"sql": "SELECT temp FROM '\''osaka/factory_a/thermometer/demo-device'\''",
"description": "Rule to send temperature to CloudWatch metrics",
"actions": [{
"cloudwatchMetric": {
"metricName": "temp",
"metricNamespace": "IoT/Device",
"metricValue": "${temp}",
"metricUnit": "None",
"roleArn": "arn:aws:iam::<account-id>:role/demo-role-iot-rule-alart"
}
}]
}'
コンソールでも確認しておきます。
問題なく作成されてますね。
IoT Coreのルールでは転送先のCloudWatchメトリクスのディメンションは指定できません。
なので、次に作成するCloudWatchメトリクスではディメンションはなし(None)にしておきます。
CloudWatch
CloudWatch メトリクス
最初にIoT Coreからデータを受け取るCloudWatchメトリクスを作成します。
以下のパラメータで作成します。
パラメータ | 値 |
---|---|
名前空間 | IoT/Device |
aws cloudwatch put-metric-data \
--region ap-northeast-1 \
--namespace "IoT/Device" \
--value 0
CloudWatchメトリクスに新しいカスタム名前空間が作成されているのが分かりますね。
CloudWatch アラーム
先ほど作成したメトリクスに対してアラームを設定します。
SNS トピック
アラームを作る前にアラート発行時にメールを通知するためのSNSトピックを作成しておきます。
aws sns create-topic --name demo-topic-alart --region ap-northeast-1
#以下はレスポンス
{
"TopicArn": "arn:aws:sns:ap-northeast-1:<account-id>:demo-topic-alart"
}
レスポンスのARNを控えておきましょう。
次にトピックをサブスクライブするメールアドレスを設定します。
トピック作成時のレスポンスのARNとサブスクライブするメールアドレスを入力します。
aws sns subscribe --topic-arn <トピックのARN> \
--region ap-northeast-1 \
--protocol email \
--notification-endpoint \
<your-email>@example.com
設定したメールアドレス宛に検証メールが届くので、「Confirm subscription」をクリックします。
これでSNSの設定は完了です。
しきい値を超えた場合のアラーム
今回はtempの値が30.0を超えた場合にアラートを発行したいと思います。
以下のパラメータで作成していきます。
パラメータ | 値 |
---|---|
アラーム名 | temp-threshold |
名前空間 | IoT/Device |
メトリクス名 | temp |
期間 | 60 |
評価期間 | 1 |
しきい値 | 30.0 |
統計 | 最大値 |
比較演算子 | しきい値より大きい |
欠落データの扱い | 無視 |
通知 | 異常時、正常に回復した時 |
aws cloudwatch put-metric-alarm \
--region ap-northeast-1 \
--alarm-name "temp-threshold" \
--namespace "IoT/Device" \
--metric-name "temp" \
--period 60 \
--evaluation-periods 1 \
--threshold 30.0 \
--statistic Maximum \
--comparison-operator GreaterThanThreshold \
--treat-missing-data ignore \
--alarm-actions arn:aws:sns:ap-northeast-1:<account-id>:demo-topic-alart \
--ok-actions arn:aws:sns:ap-northeast-1:<account-id>:demo-topic-alart
しきい値を下回った場合のアラーム設定の肝は --ok-actions
オプションです。
--ok-actions
はコンソール画面だと画像の箇所です。
--ok-actions
とすることで状態が変化(回復)した場合にも通知が発行されます。
こちらのブログでも紹介されています。
コンソール画面でも確認しておきます。
新しいアラームが作成されていますね。
動作確認
それでは実際にデータを入れてアラートの発報を確認してみます。
まずは正常な状態を確認するためにtempが30.0以下のデータを入れてみます。
以下のようなテストデータをIoT Coreのテストクライアントでいくつか発行して正常な状態を確認します。
{
"deviceid": "a1234",
"temp": 22.3
}
CloudWatch側でメトリクスを取得していることを確認します。
正常値としてデータが記録されていますね。
それでは同じ要領で30.0を超える値を入れてみましょう。
少し待つとアラームが発行されました。
アラームを確認してみます。
想定通り、30.0を超えたことでアラーム状態になっています。
また、アラートに連動してメールも通知されています。
では、次は30.0以下のデータを入れてアラートが消え、回復通知が発報されるとことを確認してみます。
(データを入れるタイミングが遅かったので、少し見ずらいですが10:03~04のあたりですね)
左側のアラームの部分が回復しているのがわかりますね。
メールでもアラートが解除された旨が通知されています。
これで一通りの仕組み作りは完了です!
削除
最後に、検証で使用した各リソースを削除しておきます。
$ aws iam delete-role-policy --role-name demo-role-iot-rule-alart --policy-name demo-inline-policy-iot-rule-alart
$ aws iam delete-role --role-name demo-role-iot-rule-alart
$ aws iot delete-topic-rule --rule-name demo_iot_rule_temp_monitor
$ aws sns delete-topic --topic-arn arn:aws:sns:ap-northeast-1:<accout-id>:demo-topic-alart
$ aws cloudwatch delete-alarms --alarm-names temp-threshold
ちなみに、カスタムメトリクスは手動で削除できません。
まとめ
IoT Coreで受け取ったデータをCloudWatchに流してアラート発砲〜アラート解除までの流れを作成してみました。
あまり細かいカスタマイズはできませんが、簡単なしきい値ベースのアラート通知であればすぐに実装できることがわかりました。